package com.ayz.gateway.server.grpc;

import cn.hutool.core.thread.ThreadFactoryBuilder;

import com.ayz.gateway.server.RemotingServer;
import com.ayz.gateway.server.grpc.connection.AddressTransportFilter;
import com.ayz.gateway.server.grpc.connection.ConnectionManger;
import com.ayz.gateway.server.grpc.connection.GrpcConnectionInterceptor;
import io.grpc.*;
import lombok.Data;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName GrpcRemotingServer
 * @Description TODO:Grpc的服务端
 * @Author 快乐的星球
 * @Date 2023/5/17 23:07
 * @Version 1.0
 **/
@Data
public class GrpcRemotingServer implements RemotingServer {
    /**
     * GRPC服务端的配置项
     */
    private GrpcServerConfig serverConfig;
    /**
     * GRPC的服务器
     */
    private Server server;
    /**
     * GRPC服务端处理任务的线程池
     */
    private ThreadPoolExecutor grpcExecutor;
    /**
     * grpc服务端的连接管理器
     */
    private ConnectionManger connectionManger;
    /**
     * 当前GRPC服务端发布的服务列表
     */
    private final List<BindableService> bindableServiceList=new ArrayList<>();
    public GrpcRemotingServer(GrpcServerConfig serverConfig) {
        this.serverConfig = serverConfig;
    }

    public void addServices(List<BindableService> bindableServiceList){
        this.bindableServiceList.addAll(bindableServiceList);
    }

    public void addService(BindableService service){
        this.bindableServiceList.add(service);
    }
    @Override
    public int getListenPort() {
        return serverConfig.getListenPort();
    }
    @Override
    public void start() throws Exception {
        //1: 先构建GRPC通信服务端的任务处理线程池
        int corePoolSize = this.serverConfig.getCorePoolSize();
        int maxPoolSize = this.serverConfig.getMaxPoolSize();
        int maxTaskQueueSize = this.serverConfig.getMaxTaskQueueSize();
        this.grpcExecutor=new ThreadPoolExecutor(corePoolSize,maxPoolSize,60, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(maxTaskQueueSize),new ThreadFactoryBuilder().setDaemon(true).setNamePrefix("ApiGatewayServerThread_").build());
        //2: 构建连接管理器
        //2.1: 获取本机的地址
        InetAddress localHost = InetAddress.getLocalHost();
        int listenPort=getListenPort();
        this.connectionManger=new ConnectionManger(ConnectionManger.generateAddress(localHost.getHostAddress(),listenPort));
        //3: 构建grpc服务端
        ServerBuilder<?> builder = ServerBuilder.forPort(getListenPort()).executor(getGrpcExecutor())
                .maxInboundMessageSize(getServerConfig().getMaxInboundMessageSize())
                .compressorRegistry(CompressorRegistry.getDefaultInstance())
                .decompressorRegistry(DecompressorRegistry.getDefaultInstance())
                .addTransportFilter(new AddressTransportFilter(getConnectionManger()))
                .keepAliveTime(getServerConfig().getServerKeepaliveTime(), TimeUnit.MILLISECONDS)
                .keepAliveTimeout(getServerConfig().getServerKeepaliveTimeout(), TimeUnit.MILLISECONDS)
                .permitKeepAliveTime(getServerConfig().getGrpcPermitKeepAliveTime(), TimeUnit.MILLISECONDS);
        addServicesHelper(builder);
        //简单服务端的拦截器 一元服务端拦截器
        builder.intercept(new GrpcConnectionInterceptor());
        this.server=builder.build();
        //启动服务端
        this.server.start();
    }
    private void addServicesHelper(ServerBuilder<?> builder) {
        List<BindableService> bindableServiceList = this.bindableServiceList;
        if(!bindableServiceList.isEmpty()){
            for (BindableService bindableService : bindableServiceList) {
                builder.addService(bindableService);
            }
        }
    }

    @Override
    public void shutdown() {
        this.server.shutdown();
    }
}
